﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Xml;

public static class XmlElementExtensionMethods
{
    private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(XmlElement));

    public static string SelectSingleNodeInnerTextByLocalName(this XmlElement xe, string name, bool isOptional)
    {
        Contract.Requires(xe != null);
        Contract.Requires(!string.IsNullOrEmpty(name));

        // select node
        var elem = xe.SelectSingleNode("./*[local-name()='" + name + "']") as XmlElement;

        if (elem == null)
        {
            if (isOptional)
                return null;

            throw new ArgumentException("element not found: " + name, "name");
        }

        return elem.InnerText.Trim();
    }

    public static Uri SelectSingleNodeInnerTextByLocalNameAsUrl(this XmlElement xe, string name, bool isOptional)
    {
        Contract.Requires(xe != null);

        var url = xe.SelectSingleNodeInnerTextByLocalName(name, isOptional);

        if (string.IsNullOrEmpty(url))
            return null;

        try
        {
            return new Uri(url, UriKind.Absolute);
        }
        catch (UriFormatException x)
        {
            // second try
            if (url.StartsWith("www."))
            {
                try
                {
                    return new Uri("http://" + url, UriKind.Absolute);
                }
                catch (Exception xx)
                {
                    _log.Error("Failed to parse URL: " + url, xx);

                    throw;
                }
            }

            // no second try
            _log.Error("Failed to parse URL: " + url, x);

            throw;
        }
        catch (Exception x)
        {
            _log.Error("Failed to parse URL: " + url, x);

            throw;
        }
    }

    public static Uri SelectSingleNodeInnerTextByLocalNameAsUrl(this XmlElement xe, Uri baseUrl, string name, bool isOptional)
    {
        Contract.Requires(xe != null);
        Contract.Requires(baseUrl != null);

        var url = xe.SelectSingleNodeInnerTextByLocalName(name, isOptional);

        if (string.IsNullOrEmpty(url))
            return null;

        try
        {
            return new Uri(baseUrl, url);
        }
        catch (Exception x)
        {
            _log.Error("Failed to parse URL: " + url, x);

            throw;
        }
    }

}
